SIZE = 100
SPACING = 150
XCOUNT = 300
YCOUNT = 200

--display:create ( "Culling Demo", 800, 600, 32, true )

local dm = DisplayMode ( )
dm.width = 800
dm.height = 600
dm.depth = 32
dm.windowed = true
display:set_mode ( dm )


scene = Layer ( )
camera = Camera ( )

scene:add_child ( camera )
display.viewport.camera = camera

-- help
font = Font ( )
font:load_system ( "Courier New", 12 )
sprite = Sprite ( )
display.viewport:add_child ( sprite )
sprite.depth = -1
sprite.canvas:set_font ( font )

help = true

timer = Timer ( )
timer:start ( 1, true )
timer.on_tick = function ( timer )
	local lh = font:get_height ( )
	local x = -800 / 2 + ( lh - font:get_size ( ) )
	local y = 600 / 2
	local fps = 1000 / timer:get_delta ( )
	local zoom = 1 / camera.scalex * 100
	local lh = font:get_height ( )
	local c = sprite.canvas
	c:clear ( )

	if help == false then
		return
	end

	c:move_to ( x, y - lh )
	c:write ( "Efficient culling of a scene containing " .. XCOUNT * YCOUNT .. " sprites" )
	c:move_to ( x, y - lh * 2 )
	c:write ( "FPS - " .. fps )
	c:move_to ( x, y - lh * 3 )
	c:write ( "Zoom - " .. camera.scalex )
	c:move_to ( x, y - lh * 4 )
	c:write ( "MBUTTON_LEFT - rotate camera" )
	c:move_to ( x, y - lh * 5 )
	c:write ( "MBUTTON_RIGHT - move camera" )
	c:move_to ( x, y - lh * 6 )
	c:write ( "WHEEL - zoom in and out" )
	c:move_to ( x, y - lh * 7 )
	c:write ( "KEY_F1 - toggle help" )
end


-- create a shared canvas for instancing
SHARED = Canvas ( )
SHARED:square ( SIZE )
SHARED:set_fill_style ( ORANGE, 1 )
SHARED:fill ( )

-- generate an array of sprites
for x = 0, XCOUNT do
	for y = 0, YCOUNT do
		local x = x * SPACING - ( XCOUNT / 2 * SPACING )
		local y = y * SPACING - ( YCOUNT / 2 * SPACING )
		local temp = Sprite ( x, y )
		temp.canvas = SHARED 
		scene:add_child ( temp )
	end
end

if mouse then
	-- allow zooming the camera via the wheel
	mouse.on_wheelmove = function ( mouse, z )
		if ( z < 0 ) then
			z = 1.1
		else
			z = 0.9
		end
		camera:change_scale ( z, z )
	end

	-- allow moving the camera via the mouse
	mouse.on_move = function ( mouse, x, y )
		if mouse:is_down ( MBUTTON_RIGHT ) then
			local r = -math.rad ( camera.rotation )

			local cos_d = math.cos ( r )
			local sin_d = math.sin ( r )

			local tx = cos_d * x - sin_d * y
			local ty = cos_d * y + sin_d * x

			tx = tx * camera.scalex
			ty = ty * camera.scaley
			camera:change_position ( -tx, -ty )
		end
		if mouse:is_down ( MBUTTON_LEFT ) then
			camera.rotation = camera.rotation + y / 2 + x / 2
		end
	end
end

if keyboard then
	keyboard.on_press = function ( keyboard, key )
		if key == KEY_F1 then
			help = not help
		end
	end
end